<?php

namespace fastphp\util;

use fastphp\facade\Config;

/**
 * 通用日志工具类
 */
class Log
{
    const DEBUG = 'debug';
    const INFO = 'info';
    const WARNING = 'warning';
    const ERROR = 'error';
    const CRITICAL = 'critical'; // 新增最高级别

    // 日志级别
    private static $logLevel = self::ERROR;

    // 缓存日志目录状态，避免重复检查
    private static $dirsCreated = [];

    /**
     * 设置日志级别
     */
    public static function setLogLevel($level)
    {
        self::$logLevel = $level;
    }

    /**
     * 通用日志写入方法
     */
    public static function write($message, $level = self::INFO, $category = 'app')
    {
        // 检查日志级别 - 快速路径，避免不必要的操作
        $levels = [self::DEBUG => 0, self::INFO => 1, self::WARNING => 2, self::ERROR => 3, self::CRITICAL => 4];
        if (!isset($levels[$level]) || $levels[$level] < $levels[self::$logLevel]) {
            return;
        }

        // 使用已定义的常量
        $logDir = defined('LOG_PATH') ? LOG_PATH : './logs';
        $categoryDir = $logDir . '/' . $category;

        // 检查目录是否已创建（缓存结果避免重复检查）
        if (!isset(self::$dirsCreated[$categoryDir])) {
            if (!is_dir($categoryDir)) {
                @mkdir($categoryDir, 0777, true); // 使用@抑制错误警告
            }
            self::$dirsCreated[$categoryDir] = true;
        }

        $fileName = $categoryDir . '/' . date('Y-m-d') . '.log';
        $logEntry = date("Y-m-d H:i:s") . " [{$level}] " . $message . "\n";

        // 使用file_put_contents替代File类，减少依赖和开销
        return @file_put_contents($fileName, $logEntry, FILE_APPEND);
    }

    // 保留原有方法，但简化实现
    public static function debug($message, $category = 'app')
    {
        // 在生产环境快速跳过调试日志
        if (self::$logLevel !== self::DEBUG) return;
        return self::write($message, self::DEBUG, $category);
    }

    // 保留原有数据库日志方法的兼容性
    public static function dbLogWrite($data, $executionTime)
    {
        return self::write("{$executionTime} - {$data}", self::INFO, 'db');
    }

    public static function dbErrLogWrite($data)
    {
        return self::write($data, self::ERROR, 'db_error');
    }

    public static function info($message, $category = 'app')
    {
        return self::write($message, self::INFO, $category);
    }

    public static function warning($message, $category = 'app')
    {
        return self::write($message, self::WARNING, $category);
    }

    public static function error($message, $category = 'app')
    {
        return self::write($message, self::ERROR, $category);
    }

    // 新增critical级别方法
    public static function critical($message, $category = 'app')
    {
        return self::write($message, self::CRITICAL, $category);
    }

    /**
     * 记录异常信息
     * @param \Throwable $e 异常对象
     * @param string $category 日志类别
     */
    public static function logException($e, $category = 'exception')
    {
        $message = get_class($e) . ": {$e->getMessage()} in {$e->getFile()} on line {$e->getLine()}\n";
        $message .= "Stack trace:\n{$e->getTraceAsString()}";
        return self::error($message, $category);
    }
}
